package com.dxysun.spring.beans.support;

import com.dxysun.spring.beans.config.DXYBeanDefinition;

import java.io.File;
import java.io.InputStream;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Properties;

public class DXYBeanDefinitionReader
{
	private Properties contextConfig = new Properties();

	private List<String> registryBeanClasses = new ArrayList<String>();

	public DXYBeanDefinitionReader(String[] configLocations)
	{
		// 1、加载配置
		doLoadConfig(configLocations);

		// 2、扫描配置下的类
		doScanner(contextConfig.getProperty("scanPackage"));
	}

	public Properties getContextConfig()
	{
		return contextConfig;
	}

	private void doLoadConfig(String[] contextLocations)
	{
		for (String config : contextLocations)
		{
			try (InputStream in = this.getClass().getClassLoader().getResourceAsStream(config))
			{
				Properties properties = new Properties();
				properties.load(in);
				contextConfig.putAll(properties);
			}
			catch (Exception e)
			{
				e.printStackTrace();
				throw new RuntimeException("获取配置异常");
			}
		}

	}

	private void doScanner(String scanPackage)
	{
		String path = scanPackage.replaceAll("\\.", "/");
		URL url = this.getClass().getClassLoader().getResource(path);
		if (url == null)
		{
			return;
		}
		File dirFile = new File(url.getPath());
		for (File file : Objects.requireNonNull(dirFile.listFiles()))
		{
			if (file.isDirectory())
			{
				doScanner(scanPackage + "." + file.getName());
			}
			if (file.getName().endsWith(".class"))
			{
				String clazzName = (scanPackage + "." + file.getName().replace(".class", ""));
				registryBeanClasses.add(clazzName);
			}
		}
	}

	public List<DXYBeanDefinition> loadBeanDefinitions()
	{
		List<DXYBeanDefinition> beanDefinitionList = new ArrayList<>();

		try
		{
			for (String className : registryBeanClasses)
			{
				Class<?> clazz = Class.forName(className);
				if (clazz.isInterface())
				{
					continue;
				}
				beanDefinitionList.add(doCreateBeanDefinition(clazz.getSimpleName(), clazz.getName()));

				Class<?>[] clazzInterfaces = clazz.getInterfaces();
				for (Class<?> clazzInterface : clazzInterfaces)
				{
					beanDefinitionList.add(doCreateBeanDefinition(clazzInterface.getSimpleName(), clazz.getName()));
				}

			}
		}
		catch (Exception e)
		{
			e.printStackTrace();
		}

		return beanDefinitionList;
	}

	private DXYBeanDefinition doCreateBeanDefinition(String beanName, String beanClassName)
	{
		DXYBeanDefinition beanDefinition = new DXYBeanDefinition();
		beanDefinition.setBeanName(toFistLowerCase(beanName));
		beanDefinition.setBeanClassName(beanClassName);
		return beanDefinition;
	}

	private String toFistLowerCase(String beanName)
	{
		char[] chars = beanName.toCharArray();
		chars[0] += 32;
		return String.valueOf(chars);
	}

}
